package logger

import (
	"fmt"
	"log"
	"os"
)

type Logger interface {
	Trace(v ...interface{})
	Debug(v ...interface{})
	Info(v ...interface{})
	Warn(v ...interface{})
	Error(v ...interface{})
	Fatal(v ...interface{})
	Panic(v ...interface{})

	Tracef(format string, v ...interface{})
	Debugf(format string, v ...interface{})
	Infof(format string, v ...interface{})
	Warnf(format string, v ...interface{})
	Errorf(format string, v ...interface{})
	Fatalf(format string, v ...interface{})
	Panicf(format string, v ...interface{})
}

type ConsoleLog struct {
	l *log.Logger
}

func NewConsoleLog() *ConsoleLog {
	l := log.New(os.Stdout, "", log.LstdFlags|log.Lshortfile)
	return &ConsoleLog{
		l: l,
	}
}

func (d ConsoleLog) Trace(v ...interface{}) {
	s := fmt.Sprint(v...)
	d.l.Output(2, "[Trace] "+s)
}

func (d ConsoleLog) Debug(v ...interface{}) {
	s := fmt.Sprint(v...)
	d.l.Output(2, "[Debug] "+s)
}

func (d ConsoleLog) Info(v ...interface{}) {
	s := fmt.Sprint(v...)
	d.l.Output(2, "[Info] "+s)
}

func (d ConsoleLog) Warn(v ...interface{}) {
	s := fmt.Sprint(v...)
	d.l.Output(2, "[Warn] "+s)
}

func (d ConsoleLog) Error(v ...interface{}) {
	s := fmt.Sprint(v...)
	d.l.Output(2, "[Error] "+s)
}

func (d ConsoleLog) Fatal(v ...interface{}) {
	s := fmt.Sprint(v...)
	d.l.Output(2, "[Fatal] "+s)
}

func (d ConsoleLog) Panic(v ...interface{}) {
	s := fmt.Sprint(v...)
	d.l.Output(2, "[Panic] "+s)
}

func (d ConsoleLog) Tracef(format string, v ...interface{}) {
	s := fmt.Sprintf(format, v...)
	d.l.Output(2, "[Trace] "+s)
}

func (d ConsoleLog) Debugf(format string, v ...interface{}) {
	s := fmt.Sprintf(format, v...)
	d.l.Output(2, "[Debug] "+s)
}

func (d ConsoleLog) Infof(format string, v ...interface{}) {
	s := fmt.Sprintf(format, v...)
	d.l.Output(2, "[Info] "+s)
}

func (d ConsoleLog) Warnf(format string, v ...interface{}) {
	s := fmt.Sprintf(format, v...)
	d.l.Output(2, "[Warn] "+s)
}

func (d ConsoleLog) Errorf(format string, v ...interface{}) {
	s := fmt.Sprintf(format, v...)
	d.l.Output(2, "[Error] "+s)
}

func (d ConsoleLog) Fatalf(format string, v ...interface{}) {
	s := fmt.Sprintf(format, v...)
	d.l.Output(2, "[Fatal] "+s)
}

func (d ConsoleLog) Panicf(format string, v ...interface{}) {
	s := fmt.Sprintf(format, v...)
	d.l.Output(2, "[Panic] "+s)
}
